package com.common.common;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.common.common.msg.ResultMsg;
import com.common.common.option.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 通用Controller
 * @param <S> 服务类
 * @param <T> 实体类
 * @param <K> 主键类
 *
 * @author liujun
 * @date 2024/10/10
 */
public class CommonController<S extends CommonServiceImpl<? extends BaseMapper<T>, T, K>, T, K extends Serializable> {
    @Autowired
    private S service;

    public S getService() {
        return service;
    }

    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") {{
            setLenient(false);
        }}, false));
    }

    @GetMapping("/getById")
    public ResultMsg<T> getById(@RequestParam("id") K id) {
        return ResultMsg.success("查询成功", service.getById(id));
    }

    @GetMapping("/empty")
    public ResultMsg<T> empty() throws IllegalAccessException, InstantiationException {
        return ResultMsg.success("查询成功", service.getEntityClass().newInstance());
    }

    @PostMapping("/one")
    public ResultMsg<T> one(@RequestBody(required = false) QueryCondition condition) {
        if (condition == null) {
            return ResultMsg.success("查询成功", service.getOne(Wrappers.emptyWrapper()));
        }
        return ResultMsg.success("查询成功", service.getOne(condition.toQueryWrapper()));
    }

    @PostMapping("/list")
    public ResultMsg<List<T>> list(@RequestBody(required = false) QueryPageOption<T> queryOptions) {
        if (queryOptions == null) {
            return ResultMsg.success("查询成功", service.list());
        }
        return ResultMsg.success("查询成功", service.list(queryOptions.toQueryWrapper()));
    }

    @PostMapping("/page")
    public QueryPageOption<T> page(@RequestBody(required = false) QueryPageOption<T> pageParams) {
        if (pageParams == null) {
            pageParams = new QueryPageOption<>();
        }
        Page<T> page = service.page(pageParams.toPage(), pageParams.toQueryWrapper());
        return pageParams.success("查询成功").setData(page.getRecords()).setPagination(new PageOption(page.getCurrent(), page.getSize(), page.getTotal()));
    }

    @PutMapping("/save")
    public ResultMsg<Void> save(@RequestBody T entity) {
        return service.saveMsg(entity);
    }

    @PutMapping("/update")
    public ResultMsg<Void> update(@RequestBody T entity) {
        return service.updateMsg(entity);
    }

    @PutMapping("/saveOrUpdate")
    public ResultMsg<Void> saveOrUpdate(@RequestBody T entity) {
        return service.saveOrUpdateMsg(entity);
    }

    @DeleteMapping("/removeByIds")
    public ResultMsg<Void> removeByIds(@RequestBody List<K> ids) {
        return service.removeByIdsMsg(ids);
    }
    
    @PostMapping("/importTemplate")
    public void importTemplate(HttpServletResponse response, @RequestBody ExcelOption<T> option) throws IOException {
        service.exportExcel(new ArrayList<>(), option.getColumns(), response, option.getSheet());
    }
    
    @PostMapping("/importData")
    public ResultMsg<Void> importData(MultipartFile file, String sheet, String columns) throws IOException {
        List<ColumnOption> _columns = JSONUtil.toList(JSONUtil.parseArray(columns), ColumnOption.class);
        return service.importExcel(file, sheet, _columns);
    }

    @PostMapping("/export")
    public void export(HttpServletResponse response, @RequestBody ExcelOption<T> option) throws IOException {
        QueryPageOption<T> queryPageOption = option.getOption();
        PageOption pagination = queryPageOption.getPagination();
        List<T> data = pagination == null ? list(queryPageOption).getData() : page(queryPageOption).getData();
        service.exportExcel(data, option.getColumns(), response, option.getSheet());
    }
}
